﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Admx_Generator
{
    public partial class FrmAddAdmx : Form
    {
        public enum AddingMethod
        {
            Import,
            Create
        }

        public FrmAddAdmx()
        {
            InitializeComponent();

            this.SetupUI();
        }

        #region {properties}

        /// <summary>
        /// Gets or Sets if the user wants to import an existing Admx or to create a new one.
        /// </summary>
        internal AddingMethod Method { get; private set; }

        internal string FilenameToImport { get; private set; }

        internal string FilenameToCreate { get; private set; }

        internal Namespace TargetedNamespace { get; private set; }

        internal culture FallbackCulture { get; private set; }

        #endregion {properties}

        #region {private methods}

        private void SetupUI()
        {
            List<char> allowedChars = Utilities.GetAllowedCharacters();
            char[] invalideCharacters = System.IO.Path.GetInvalidFileNameChars();

            // FilterTextBox Filename
            try
            {
                this.fltTxtBxAdmxToCreate.DisallowedCharacters.AddRange(invalideCharacters);
            }
            catch (Exception) { }

            // FilterTextBox Namespace
            try
            {
                this.fltTxtBxNamespace.AllowedCharacters.AddRange(allowedChars);
                this.fltTxtBxNamespace.AllowedCharacters.Add('.');
                this.fltTxtBxNamespace.Text = Properties.Settings.Default.DefaultTargetNamespace;
            }
            catch (Exception) { }

            // FilterTextBox Prefix
            try
            {
                this.fltTxtBxPrefix.AllowedCharacters.AddRange(allowedChars);
                this.fltTxtBxPrefix.AllowedCharacters.Add('_');
            }
            catch (Exception) { }

            // ComboBox Fallback Culture

            this.cmbBxFallbackCulture.Enabled = false;

            System.Threading.Tasks.Task SetupLanguage = new System.Threading.Tasks.Task(() =>
            {
                string allLanguages = Properties.Resources.LanguageCodes;
                string[] codes = allLanguages.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);

                string FallbackCulture = this.GetFallbackCultureFromOptions();
                foreach (string code in codes)
                {
                    try
                    {
                        culture newCulture = new culture(new System.Globalization.CultureInfo(code));
                        Action addLanguage = () =>
                        {
                            this.cmbBxFallbackCulture.Items.Add(newCulture);
                        };
                        this.Invoke(addLanguage);
                        if (String.Compare(code, FallbackCulture, true) == 0)
                        {
                            Action selecteFallbackCulture = () =>
                            { this.cmbBxFallbackCulture.SelectedItem = newCulture; };
                            this.Invoke(selecteFallbackCulture);
                        }
                    }
                    catch (Exception) { }
                }
                Action enableComboBox = () =>
                {
                    this.cmbBxFallbackCulture.Enabled = true;
                    this.ValidateData();
                };
                this.Invoke(enableComboBox);
            });
            SetupLanguage.Start();
        }

        /// <summary>
        /// Check user entries and allow or disallow the 'Ok' button accordingly
        /// </summary>
        private void ValidateData()
        {
            if (this.rdBtnImportAdmx.Checked)
            {
                this.btnOk.Enabled = !String.IsNullOrEmpty(this.txtBxAdmxToImport.Text) && System.IO.File.Exists(this.txtBxAdmxToImport.Text);
            }
            else
            {
                bool namespaceOK = !String.IsNullOrEmpty(this.fltTxtBxNamespace.Text) && this.fltTxtBxNamespace.Text.Contains('.') && !this.fltTxtBxNamespace.Text.EndsWith(".");
                bool prefixOK = !String.IsNullOrEmpty(this.fltTxtBxPrefix.Text);
                bool filenameOK = !String.IsNullOrEmpty(this.fltTxtBxAdmxToCreate.Text) && Utilities.IsValidFilename(this.fltTxtBxAdmxToCreate.Text);
                bool fallbackCultureOK = this.cmbBxFallbackCulture.SelectedIndex != -1;

                // Displays UI clues
                this.fltTxtBxNamespace.BackColor = namespaceOK ? SystemColors.Window : Color.DarkOrange;
                this.fltTxtBxPrefix.BackColor = prefixOK ? SystemColors.Window : Color.DarkOrange;
                this.fltTxtBxAdmxToCreate.BackColor = filenameOK ? SystemColors.Window : Color.DarkOrange;

                this.btnOk.Enabled = namespaceOK && prefixOK && filenameOK && fallbackCultureOK;
            }
        }

        /// <summary>
        /// Return the fallback culture as it is set in application settings
        /// </summary>
        /// <returns>The fallback culture choose by the user in the options</returns>
        private string GetFallbackCultureFromOptions()
        {
            string fallbackCulture = String.Empty;

            switch (Properties.Settings.Default.FallbackCultureOption)
            {
                case "MyCulture":
                    fallbackCulture = System.Threading.Thread.CurrentThread.CurrentCulture.Name;
                    break;
                case "en-US":
                    fallbackCulture = "en-US";
                    break;
                case "ThisOne":
                    fallbackCulture = Properties.Settings.Default.FallBackCultureThisOne;
                    break;
            }

            return fallbackCulture;
        }

        #endregion {private methods}

        #region {UI Management}

        private void rdBtnImportAdmx_CheckedChanged(object sender, EventArgs e)
        {
            bool import = rdBtnImportAdmx.Checked;

            this.txtBxAdmxToImport.Enabled = import;
            this.btnBrowse.Enabled = import;
            this.fltTxtBxAdmxToCreate.Enabled = !import;
            this.fltTxtBxNamespace.Enabled = !import;
            this.fltTxtBxPrefix.Enabled = !import;
            this.cmbBxFallbackCulture.Enabled = !import;

            this.ValidateData();
        }

        private void control_TextChanged(object sender, EventArgs e)
        {
            if (sender.GetType() == typeof(EasyCompany.Controls.FilteredTextbox))
            {
                EasyCompany.Controls.FilteredTextbox ctrl = (EasyCompany.Controls.FilteredTextbox)sender;
                if (ctrl == this.fltTxtBxAdmxToCreate && !String.IsNullOrEmpty(this.fltTxtBxAdmxToCreate.Text))
                {
                    this.fltTxtBxNamespace.Text = this.fltTxtBxNamespace.FilterText(Properties.Settings.Default.DefaultTargetNamespace + this.fltTxtBxAdmxToCreate.Text);
                    this.fltTxtBxPrefix.Text = this.fltTxtBxPrefix.FilterText(this.fltTxtBxAdmxToCreate.Text);
                }
            }

            this.ValidateData();
        }

        private void btnBrowse_Click(object sender, EventArgs e)
        {
            OpenFileDialog openDlg = new OpenFileDialog();

            openDlg.Filter = "Admx|*.admx";

            if (openDlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                this.txtBxAdmxToImport.Text = openDlg.FileName;
            }
            this.ValidateData();
        }

        private void btnOk_Click(object sender, EventArgs e)
        {
            if (this.rdBtnImportAdmx.Checked)
            {
                this.Method = AddingMethod.Import;
                this.FilenameToImport = this.txtBxAdmxToImport.Text;
            }
            else
            {
                this.Method = AddingMethod.Create;
                this.FilenameToCreate = this.fltTxtBxAdmxToCreate.Text;
                this.TargetedNamespace = new Namespace(this.fltTxtBxNamespace.Text, this.fltTxtBxPrefix.Text);
                this.FallbackCulture = (culture)this.cmbBxFallbackCulture.SelectedItem;
            }
            DialogResult = System.Windows.Forms.DialogResult.OK;
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            DialogResult = System.Windows.Forms.DialogResult.Cancel;
        }

        private void txtControl_Enter(object sender, EventArgs e)
        {
            TextBox txtControl = (TextBox)sender;

            txtControl.Select(txtControl.Text.Length, 0);
        }

        private void lnkNamespaceNamingGuidelines_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            try
            {
                System.Diagnostics.Process.Start(@"http://msdn.microsoft.com/en-us/library/893ke618(v=vs.71).aspx");
                System.Threading.Thread.Sleep(1000);
                System.Diagnostics.Process.Start(@"http://msdn.microsoft.com/en-us/library/xzf533w0(v=vs.71).aspx");
            }
            catch (Exception) { }
        }

        #endregion {UI Management}
    }
}
